﻿using System.Collections.Concurrent;

namespace SimpleScheduler
{
    public sealed class SimpleSchedulerFactory
    {
        static readonly ConcurrentDictionary<string, DelayQueue> dictQueue;
        static readonly ConcurrentDictionary<string, ScheduleQueue> dictSchedule;
        static SimpleSchedulerFactory()
        {
            dictQueue = new ConcurrentDictionary<string, DelayQueue>();
            dictSchedule = new ConcurrentDictionary<string, ScheduleQueue>();
        }

        static bool Exist(DelayQueueKey key)
        {
            foreach (var item in dictQueue)
            {
                if (!string.Equals(item.Key, key.QueueName))
                {
                    bool exist = item.Value.Exist(key);
                    if (exist)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 创建队列
        /// </summary>
        /// <param name="queueName">队列名称</param>
        /// <returns></returns>
        public static IDelayQueue CreateDelayQueue(string queueName)
        {
            if(dictQueue.TryGetValue(queueName, out var queue))
            {
                return queue;
            }
            queue = new DelayQueue(queueName, new QueueOptions());
            dictQueue.TryAdd(queueName, queue);
            queue.Start();
            return queue;
        }

        /// <summary>
        /// 创建队列
        /// </summary>
        /// <param name="queueName">队列名称</param>
        /// <param name="opts">队列设置项</param>
        /// <returns></returns>
        public static IDelayQueue CreateDelayQueue(string queueName, QueueOptions opts)
        {
            if (dictQueue.TryGetValue(queueName, out var queue))
            {
                return queue;
            }
            queue = new DelayQueue(queueName, opts ?? new QueueOptions(), Exist);
            dictQueue.TryAdd(queueName, queue);
            queue.Start();
            return queue;
        }

        /// <summary>
        /// 创建队列
        /// </summary>
        /// <param name="opts">队列设置项</param>
        /// <returns></returns>
        public static IDelayQueue CreateDelayQueue(QueueOptions opts = null)
        {
            if (dictQueue.TryGetValue(Constants.DefaultQueueName, out var queue))
            {
                return queue;
            }
            queue = new DelayQueue(Constants.DefaultQueueName, opts ?? new QueueOptions(), Exist);
            dictQueue.TryAdd(Constants.DefaultQueueName, queue);
            queue.Start();
            return queue;
        }

        /// <summary>
        /// 创建定时任务
        /// </summary>
        /// <param name="scheduleName">定时任务名称</param>
        /// <returns></returns>
        public static IScheduleTask CreateSchedule(string scheduleName)
        {
            if (dictSchedule.TryGetValue(scheduleName, out var schedule))
            {
                return schedule;
            }
            schedule = new ScheduleQueue(scheduleName, new QueueOptions());
            dictSchedule.TryAdd(scheduleName, schedule);
            schedule.Start();
            return schedule;
        }

        /// <summary>
        /// 创建定时任务
        /// </summary>
        /// <param name="scheduleName">定时任务名称</param>
        /// <param name="opts">队列设置项</param>
        /// <returns></returns>
        public static IScheduleTask CreateSchedule(string scheduleName, QueueOptions opts)
        {
            if (dictSchedule.TryGetValue(scheduleName, out var schedule))
            {
                return schedule;
            }
            schedule = new ScheduleQueue(scheduleName, opts ?? new QueueOptions(), Exist);
            dictSchedule.TryAdd(scheduleName, schedule);
            schedule.Start();
            return schedule;
        }

        /// <summary>
        /// 创建定时任务
        /// </summary>
        /// <param name="opts">定时队列设置项</param>
        /// <returns></returns>
        public static IScheduleTask CreateSchedule(QueueOptions opts = null)
        {
            if (dictSchedule.TryGetValue(Constants.DefalutScheduleName, out var schedule))
            {
                return schedule;
            }
            schedule = new ScheduleQueue(Constants.DefalutScheduleName, opts ?? new QueueOptions(), Exist);
            dictSchedule.TryAdd(Constants.DefalutScheduleName, schedule);
            schedule.Start();
            return schedule;
        }
    }
}
